<!DOCTYPE html>
<html>

<head>
  <title>Quarkus - Using Eclipse Vert.x</title>
  <script id="adobe_dtm" src="https://www.redhat.com/dtm.js" type="text/javascript"></script>
  <script src="/assets/javascript/highlight.pack.js" type="text/javascript"></script>
  <META HTTP-EQUIV='Content-Security-Policy' CONTENT="default-src 'none'; script-src 'self' 'unsafe-eval' 'sha256-ANpuoVzuSex6VhqpYgsG25OHWVA1I+F6aGU04LoI+5s=' 'sha256-ipy9P/3rZZW06mTLAR0EnXvxSNcnfSDPLDuh3kzbB1w=' js.bizographics.com https://www.redhat.com assets.adobedtm.com jsonip.com https://ajax.googleapis.com https://www.googletagmanager.com https://www.google-analytics.com https://use.fontawesome.com; style-src 'self' https://fonts.googleapis.com https://use.fontawesome.com; img-src 'self' *; media-src 'self' ; frame-src https://www.googletagmanager.com https://www.youtube.com; frame-ancestors 'none'; base-uri 'none'; object-src 'none'; form-action 'none'; font-src 'self' https://use.fontawesome.com https://fonts.gstatic.com;">
  <META HTTP-EQUIV='X-Frame-Options' CONTENT="DENY">
  <META HTTP-EQUIV='X-XSS-Protection' CONTENT="1; mode=block">
  <META HTTP-EQUIV='X-Content-Type-Options' CONTENT="nosniff">
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <meta name="description" content="Quarkus: Supersonic Subatomic Java">
  <meta name="twitter:card" content="summary_large_image">
  <meta name="twitter:site" content="@QuarkusIO"> 
  <meta name="twitter:creator" content="@QuarkusIO">
  <meta property="og:url" content="https://quarkus.io/guides/vertx" />
  <meta property="og:title" content="Quarkus - Using Eclipse Vert.x" />
  <meta property="og:description" content="Quarkus: Supersonic Subatomic Java" />
  <meta property="og:image" content="/assets/images/quarkus_card.png" />
  <link rel="canonical" href="https://quarkus.io/guides/vertx">
  <link rel="shortcut icon" type="image/png" href="/favicon.ico" >
  <link rel="stylesheet" href="https://quarkus.io/guides/stylesheet/config.css" />
  <link rel="stylesheet" href="/assets/css/main.css" />
  <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.1.0/css/all.css" integrity="sha384-lKuwvrZot6UHsBSfcMvOkWwlCMgc0TaWr+30HWe3a4ltaBwTZhyTEggF5tJv8tbt" crossorigin="anonymous">
  <link rel="alternate" type="application/rss+xml"  href="https://quarkus.io/feed.xml" title="Quarkus">
  <script src="https://quarkus.io/assets/javascript/goan.js" type="text/javascript"></script>
  <script src="https://quarkus.io/assets/javascript/hl.js" type="text/javascript"></script>
</head>

<body class="guides">
  <!-- Google Tag Manager (noscript) -->
  <noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-NJWS5L"
  height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
  <!-- End Google Tag Manager (noscript) -->

  <div class="nav-wrapper">
  <div class="grid-wrapper">
    <div class="width-12-12">
      <input type="checkbox" id="checkbox" />
      <nav id="main-nav" class="main-nav">
  <div class="container">
    <div class="logo-wrapper">
      
        <a href="/"><img src="/assets/images/quarkus_logo_horizontal_rgb_600px_reverse.png" class="project-logo" title="Quarkus"></a>
      
    </div>
    <label class="nav-toggle" for="checkbox">
      <i class="fa fa-bars"></i>
    </label>
    <div id="menu" class="menu">
      <span>
        <a href="/get-started/" class="">Get Started</a>
      </span>
      <span>
        <a href="/guides/" class="active">Guides</a>
      </span>
      <span>
        <a href="/community/" class="">Community</a>
      </span>
      <span>
        <a href="/support/" class="">Support</a>
      </span>
      <span>
        <a href="/blog/" class="">Blog</a>
      </span>
      <span>
        <a href="https://code.quarkus.io" class="button-cta secondary white">Start Coding</a>
      </span>
    </div>
  </div>
      </nav>
    </div>
  </div>
</div>

  <div class="content">
    <div class="guide">
  <div class="width-12-12">
    <h1 class="text-caps">Quarkus - Using Eclipse Vert.x</h1>
    <div class="hide-mobile toc"><ul class="sectlevel1">
<li><a href="#installing">Installing</a></li>
<li><a href="#native-transport">Native Transport</a>
<ul class="sectlevel2">
<li><a href="#native-linux-transport">Native Linux Transport</a></li>
<li><a href="#native-macos-transport">Native MacOS Transport</a></li>
</ul>
</li>
<li><a href="#accessing-vert-x">Accessing Vert.x</a></li>
<li><a href="#using-vert-x-in-reactive-jax-rs-resources">Using Vert.x in Reactive JAX-RS resources</a>
<ul class="sectlevel2">
<li><a href="#asynchronous-processing">Asynchronous processing</a></li>
<li><a href="#streaming-using-server-sent-events">Streaming using Server-Sent Events</a></li>
<li><a href="#using-vert-x-json">Using Vert.x JSON</a></li>
</ul>
</li>
<li><a href="#using-vert-x-clients">Using Vert.x Clients</a>
<ul class="sectlevel2">
<li><a href="#picking-the-right-dependency">Picking the right dependency</a></li>
</ul>
</li>
<li><a href="#deploying-verticles">Deploying verticles</a></li>
<li><a href="#listening-to-a-unix-domain-socket">Listening to a Unix Domain Socket</a></li>
<li><a href="#read-only-deployment-environments">Read only deployment environments</a></li>
<li><a href="#running-behind-a-reverse-proxy">Running behind a reverse proxy</a></li>
<li><a href="#going-further">Going further</a></li>
</ul></div>
    <div>
      <div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>Eclipse <a href="https://vertx.io">Vert.x</a> is a toolkit for building reactive applications.
It is designed to be lightweight and embeddable.
Vert.x defines a reactive execution model and provides a large ecosystem.</p>
</div>
<div class="paragraph">
<p>Quarkus is based on Vert.x, and almost all network-related features rely on Vert.x.
While lots of reactive features from Quarkus don&#8217;t <em>show</em> Vert.x, it&#8217;s used underneath.
Quarkus also integrates smoothly with the Vert.x event bus (to enable asynchronous messaging passing between application components) and some reactive clients.
You can also use various Vert.x APIs in your Quarkus application, such as deploying <em>verticles</em>, instantiating clients&#8230;&#8203;</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="installing"><a class="anchor" href="#installing"></a>Installing</h2>
<div class="sectionbody">
<div class="paragraph">
<p>To access Vert.x, well, you need to enable the <code>vertx</code> extension to use this feature.
If you are creating a new project, set the <code>extensions</code> parameter are follows:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="shell" class="language-shell hljs">mvn io.quarkus:quarkus-maven-plugin:1.7.0.Final:create \
    -DprojectGroupId=org.acme \
    -DprojectArtifactId=vertx-quickstart \
    -Dextensions="vertx"
cd vertx-quickstart</code></pre>
</div>
</div>
<div class="paragraph">
<p>If you have an already created project, the <code>vertx</code> extension can be added to an existing Quarkus project with
the <code>add-extension</code> command:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="shell" class="language-shell hljs">./mvnw quarkus:add-extension -Dextensions="vertx"</code></pre>
</div>
</div>
<div class="paragraph">
<p>Otherwise, you can manually add this to the dependencies section of your <code>pom.xml</code> file:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="xml" class="language-xml hljs">&lt;dependency&gt;
    &lt;groupId&gt;io.quarkus&lt;/groupId&gt;
    &lt;artifactId&gt;quarkus-vertx&lt;/artifactId&gt;
&lt;/dependency&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="native-transport"><a class="anchor" href="#native-transport"></a>Native Transport</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Vert.x is capable of using <a href="https://netty.io/wiki/native-transports.html">Netty&#8217;s native transports</a> which offers
performance improvements on certain platforms. To enable them you must include the appropriate dependency for your
platform. It&#8217;s usually a good idea to include both to keep your application platform agnostic. Netty is smart enough
to use the correct one, that includes none at all on unsupported platforms:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="xml" class="language-xml hljs">&lt;dependency&gt;
  &lt;groupId&gt;io.netty&lt;/groupId&gt;
  &lt;artifactId&gt;netty-transport-native-epoll&lt;/artifactId&gt;
  &lt;classifier&gt;linux-x86_64&lt;/classifier&gt;
&lt;/dependency&gt;

&lt;dependency&gt;
  &lt;groupId&gt;io.netty&lt;/groupId&gt;
  &lt;artifactId&gt;netty-transport-native-kqueue&lt;/artifactId&gt;
  &lt;classifier&gt;osx-x86_64&lt;/classifier&gt;
&lt;/dependency&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>You will also have to explicitly configure Vert.x to use the native transport. In <code>application.properties</code> add:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-none hljs">quarkus.vertx.prefer-native-transport=true</code></pre>
</div>
</div>
<div class="paragraph">
<p>Or in <code>application.yml</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="yml" class="language-yml hljs">quarkus:
  vertx:
    prefer-native-transport: true</code></pre>
</div>
</div>
<div class="paragraph">
<p>If all is well quarkus will log:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>[io.qua.ver.cor.run.VertxCoreRecorder] (main) Vertx has Native Transport Enabled: true</pre>
</div>
</div>
<div class="sect2">
<h3 id="native-linux-transport"><a class="anchor" href="#native-linux-transport"></a>Native Linux Transport</h3>
<div class="paragraph">
<p>On Linux you can enable the following socket options:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>SO_REUSEPORT</p>
</li>
</ul>
</div>
<div class="listingblock">
<div class="content">
<pre>quarkus.http.so-reuse-port=true</pre>
</div>
</div>
<div class="ulist">
<ul>
<li>
<p>TCP_QUICKACK</p>
</li>
</ul>
</div>
<div class="listingblock">
<div class="content">
<pre>quarkus.http.tcp-quick-ack=true</pre>
</div>
</div>
<div class="ulist">
<ul>
<li>
<p>TCP_CORK</p>
</li>
</ul>
</div>
<div class="listingblock">
<div class="content">
<pre>quarkus.http.tcp-cork=true</pre>
</div>
</div>
<div class="ulist">
<ul>
<li>
<p>TCP_FASTOPEN</p>
</li>
</ul>
</div>
<div class="listingblock">
<div class="content">
<pre>quarkus.http.tcp-fast-open=true</pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="native-macos-transport"><a class="anchor" href="#native-macos-transport"></a>Native MacOS Transport</h3>
<div class="paragraph">
<p>On MacOS Sierra and above you can enable the following socket options:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>SO_REUSEPORT</p>
</li>
</ul>
</div>
<div class="listingblock">
<div class="content">
<pre>quarkus.http.so-reuse-port=true</pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="accessing-vert-x"><a class="anchor" href="#accessing-vert-x"></a>Accessing Vert.x</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Once the extension has been added, you can access the <em>managed</em> Vert.x instance using <code>@Inject</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">@Inject Vertx vertx;</code></pre>
</div>
</div>
<div class="paragraph">
<p>If you are familiar with Vert.x, you know that Vert.x provides different API models.
For instance <em>bare</em> Vert.x uses callbacks, the Mutiny variants uses <code>Uni</code> and <code>Multi</code>, the RX Java 2 version uses <code>Single</code>, <code>Maybe</code>, <code>Completable</code>, <code>Observable</code> and <code>Flowable</code>&#8230;&#8203;</p>
</div>
<div class="paragraph">
<p>Quarkus provides 4 Vert.x APIs:</p>
</div>
<table class="tableblock frame-all grid-all stretch">
<colgroup>
<col style="width: 33.3333%;">
<col style="width: 33.3333%;">
<col style="width: 33.3334%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Name</th>
<th class="tableblock halign-left valign-top">Code</th>
<th class="tableblock halign-left valign-top">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><em>bare</em></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>@Inject io.vertx.core.Vertx vertx</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><em>bare</em> Vert.x instance, the API uses callbacks.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="https://smallrye.io/smallrye-mutiny/">Mutiny</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>@Inject io.vertx.mutiny.core.Vertx vertx</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">The Mutiny API for Vert.x.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">RX Java 2</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>@Inject io.vertx.reactivex.core.Vertx vertx</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">RX Java 2 Vert.x, the API uses RX Java 2 types (deprecated).</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><em>Axle</em></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>@Inject io.vertx.axle.core.Vertx vertx</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Axle Vert.x, the API uses <code>CompletionStage</code> and <code>Reactive Streams</code> (deprecated).</p></td>
</tr>
</tbody>
</table>
<div class="admonitionblock tip">
<table>
<tr>
<td class="icon">
<i class="fa icon-tip" title="Tip"></i>
</td>
<td class="content">
You may inject any of the 4 flavors of <code>Vertx</code> as well as the <code>EventBus</code> in your Quarkus application beans: <code>bare</code>, <code>Mutiny</code>, <code>Axle</code>, <code>RxJava2</code>.
They are just shims and rely on a single <em>managed</em> Vert.x instance.
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>You will pick one or the other depending on your use cases.</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>bare</code>: for advanced usage or if you have existing Vert.x code you want to reuse in your Quarkus application</p>
</li>
<li>
<p><code>mutiny</code>: Mutiny is an event-driven reactive programming API. It uses 2 types: <code>Uni</code> and <code>Multi</code>. This is the recommended API.</p>
</li>
<li>
<p><code>Axle</code>: works well with Quarkus and MicroProfile APIs (<code>CompletionStage</code> for single results and <code>Publisher</code> for streams) - deprecated, it is recommended to switch to Mutiny</p>
</li>
<li>
<p><code>Rx Java 2</code>: when you need support for a wide range of data transformation operators on your streams - deprecated, it is recommended to switch to Mutiny</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The following snippets illustrate the difference between these 4 APIs:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">// Bare Vert.x:
vertx.fileSystem().readFile("lorem-ipsum.txt", ar -&gt; {
    if (ar.succeeded()) {
        System.out.println("Content:" + ar.result().toString("UTF-8"));
    } else {
        System.out.println("Cannot read the file: " + ar.cause().getMessage());
    }
});

// Mutiny Vert.x:
vertx.fileSystem().readFile("lorem-ipsum.txt")
    .onItem().transform(buffer -&gt; buffer.toString("UTF-8"))
    .subscribe()
    .with(
            content -&gt; System.out.println("Content: " + content),
            err -&gt; System.out.println("Cannot read the file: " + err.getMessage())
    );

// Rx Java 2 Vert.x
vertx.fileSystem().rxReadFile("lorem-ipsum.txt")
    .map(buffer -&gt; buffer.toString("UTF-8"))
    .subscribe(
            content -&gt; System.out.println("Content: " + content),
            err -&gt; System.out.println("Cannot read the file: " + err.getMessage())
    );

// Axle API:
vertx.fileSystem().readFile("lorem-ipsum.txt")
    .thenApply(buffer -&gt; buffer.toString("UTF-8"))
    .whenComplete((content, err) -&gt; {
        if (err != null) {
            System.out.println("Cannot read the file: " + err.getMessage());
        } else {
            System.out.println("Content: " + content);
        }
    });</code></pre>
</div>
</div>
<div class="admonitionblock tip">
<table>
<tr>
<td class="icon">
<i class="fa icon-tip" title="Tip"></i>
</td>
<td class="content">
<div class="title">Mutiny</div>
<div class="paragraph">
<p>If you&#8217;re not familiar with Mutiny, we recommend to read the <a href="getting-started-reactive#mutiny">Getting Started with Reactive guide</a> first.</p>
</div>
</td>
</tr>
</table>
</div>
</div>
</div>
<div class="sect1">
<h2 id="using-vert-x-in-reactive-jax-rs-resources"><a class="anchor" href="#using-vert-x-in-reactive-jax-rs-resources"></a>Using Vert.x in Reactive JAX-RS resources</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Quarkus web resources support asynchronous processing and streaming results over <a href="https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events">server-sent events</a>.</p>
</div>
<div class="sect2">
<h3 id="asynchronous-processing"><a class="anchor" href="#asynchronous-processing"></a>Asynchronous processing</h3>
<div class="paragraph">
<p>To asynchronously handle the HTTP request, the endpoint method must return a <code>java.util.concurrent.CompletionStage</code> or an <code>io.smallrye.mutiny.Uni</code> (requires the <code>quarkus-resteasy-mutiny</code> extension):</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">@Path("/lorem")
public class GreetingResource {

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public Uni&lt;String&gt; doSomethingAsync() {
        // Mimic an asynchronous computation.
        return Uni.createFrom()
                .item(() -&gt; "Hello!")
                .onItem().delayIt().by(Duration.ofMillis(10));
    }
}</code></pre>
</div>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="shell" class="language-shell hljs">./mvnw compile quarkus:dev</code></pre>
</div>
</div>
<div class="paragraph">
<p>Then, open your browser to <a href="http://localhost:8080/lorem" class="bare">http://localhost:8080/lorem</a> and you should get the message.</p>
</div>
<div class="paragraph">
<p>So far so good.
Now let&#8217;s use the Vert.x API instead of this artificial delay:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">package org.acme.vertx;

import io.smallrye.mutiny.Uni;
import io.vertx.mutiny.core.Vertx;

import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Path("/lorem")
public class GreetingResource {

    @Inject
    Vertx vertx;

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public Uni&lt;String&gt; doSomethingAsync() {
        return vertx.fileSystem().readFile("/META-INF/resources/lorem.txt")
                .onItem().transform(b -&gt; b.toString("UTF-8"));
    }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>In this code, we inject the <code>vertx</code> instance (<code>io.vertx.mutiny.core.Vertx</code>) and read a file from the file system.</p>
</div>
<div class="paragraph">
<p>Create the <code>src/main/resources/META_INF/resources/lorem.txt</code> file with the following content:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="text" class="language-text hljs">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</code></pre>
</div>
</div>
<div class="paragraph">
<p>Then, refresh the page, you should see the <em>lorem ipsum</em> text.</p>
</div>
</div>
<div class="sect2">
<h3 id="streaming-using-server-sent-events"><a class="anchor" href="#streaming-using-server-sent-events"></a>Streaming using Server-Sent Events</h3>
<div class="paragraph">
<p>Quarkus web resources that need to send content as <a href="https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events">server-sent events</a> must have a method:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>declaring the <code>text/event-stream</code> response content type</p>
</li>
<li>
<p>returning a <a href="https://www.reactive-streams.org/">Reactive Streams</a> <code>Publisher</code> or Mutiny <code>Multi</code>  (requires the <code>quarkus-resteasy-mutiny</code> extension)</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>In practice, a streaming greeting service would look like:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">@Path("/hello")
public class StreamingResource {

    @GET
    @Produces(MediaType.SERVER_SENT_EVENTS)
    @Path("/{name}")
    public Multi&lt;String&gt; greeting(@PathParam String name) {
        // TODO: create a Reactive Streams publisher or a Mutiny Multi
        return publisher;
    }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Now we just need to return our <code>Publisher</code> or <code>Multi</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">package org.acme.vertx;

import io.smallrye.mutiny.Multi;
import io.vertx.mutiny.core.Vertx;
import org.jboss.resteasy.annotations.jaxrs.PathParam;

import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import java.util.Date;

@Path("/stream")
public class StreamingResource {

    @Inject
    Vertx vertx;

    @GET
    @Produces(MediaType.SERVER_SENT_EVENTS)
    @Path("/{name}")
    public Multi&lt;String&gt; greeting(@PathParam String name) {
        return vertx.periodicStream(2000).toMulti()
                .map(l -&gt; String.format("Hello %s! (%s)%n", name, new Date()));
    }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The server side is ready.
In order to see the result in the browser, we need a web page.</p>
</div>
<div class="listingblock">
<div class="title">META-INF/resources/streaming.html</div>
<div class="content">
<pre class="highlightjs highlight"><code data-lang="html" class="language-html hljs">&lt;!doctype html&gt;
&lt;html&gt;
&lt;head&gt;
    &lt;meta charset="utf-8"/&gt;
    &lt;title&gt;SSE with Vert.x - Quarkus&lt;/title&gt;
    &lt;script type="application/javascript" src="streaming.js"&gt;&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;div id="container"&gt;&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Our web page just has an empty <code>&lt;div&gt;</code> container.
The magic, as always, lies in the Javascript code:</p>
</div>
<div class="listingblock">
<div class="title">META-INF/resources/streaming.js</div>
<div class="content">
<pre class="highlightjs highlight"><code data-lang="javascript" class="language-javascript hljs">if (!!window.EventSource) {
    var eventSource = new EventSource("/stream/Quarkus");
    eventSource.onmessage = function (event) {
        var container = document.getElementById("container");
        var paragraph = document.createElement("p");
        paragraph.innerHTML = event.data;
        container.appendChild(paragraph);
    };
} else {
    window.alert("EventSource not available on this browser.")
}</code></pre>
</div>
</div>
<div class="admonitionblock important">
<table>
<tr>
<td class="icon">
<i class="fa icon-important" title="Important"></i>
</td>
<td class="content">
Most browsers support SSE but some don&#8217;t.
More about this in  Mozilla&#8217;s <a href="https://developer.mozilla.org/en-US/docs/Web/API/EventSource#Browser_compatibility">SSE browser-compatibility list</a>.
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>Navigate to <a href="http://localhost:8080/streaming.html" class="bare">http://localhost:8080/streaming.html</a>.
A new greeting should show-up every 2 seconds.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="text" class="language-text hljs">Hello Quarkus! (Wed Feb 12 17:13:55 CET 2020)

Hello Quarkus! (Wed Feb 12 17:13:57 CET 2020)

Hello Quarkus! (Wed Feb 12 17:13:59 CET 2020)

Hello Quarkus! (Wed Feb 12 17:14:01 CET 2020)

Hello Quarkus! (Wed Feb 12 17:14:03 CET 2020)

...</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="using-vert-x-json"><a class="anchor" href="#using-vert-x-json"></a>Using Vert.x JSON</h3>
<div class="paragraph">
<p>Vert.x API heavily relies on JSON, namely the <code>io.vertx.core.json.JsonObject</code> and <code>io.vertx.core.json.JsonArray</code> types.
They are both supported as Quarkus web resource request and response bodies.</p>
</div>
<div class="paragraph">
<p>Consider these endpoints:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">@Path("/hello")
@Produces(MediaType.APPLICATION_JSON)
public class VertxJsonResource {

    @GET
    @Path("{name}/object")
    public JsonObject jsonObject(@PathParam String name) {
        return new JsonObject().put("Hello", name);
    }

    @GET
    @Path("{name}/array")
    public JsonArray jsonArray(@PathParam String name) {
        return new JsonArray().add("Hello").add(name);
    }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>In your browser, navigate to <a href="http://localhost:8080/hello/Quarkus/object" class="bare">http://localhost:8080/hello/Quarkus/object</a>. You should see:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="text" class="language-text hljs">{"Hello":"Quarkus"}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Then, navigate to <a href="http://localhost:8080/hello/Quarkus/array" class="bare">http://localhost:8080/hello/Quarkus/array</a>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="text" class="language-text hljs">["Hello","Quarkus"]</code></pre>
</div>
</div>
<div class="paragraph">
<p>Needless to say, this works equally well when the JSON content is a request body or is wrapped in a <code>Uni</code>, <code>Multi</code>, <code>CompletionStage</code> or <code>Publisher</code>.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="using-vert-x-clients"><a class="anchor" href="#using-vert-x-clients"></a>Using Vert.x Clients</h2>
<div class="sectionbody">
<div class="paragraph">
<p>As you can inject a Vert.x instance, you can use Vert.x clients in a Quarkus application.
This section gives an example with the <code>WebClient</code>.</p>
</div>
<div class="sect2">
<h3 id="picking-the-right-dependency"><a class="anchor" href="#picking-the-right-dependency"></a>Picking the right dependency</h3>
<div class="paragraph">
<p>Depending on the API model you want to use you need to add the right dependency to your <code>pom.xml</code> file:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="xml" class="language-xml hljs">&lt;!-- bare API --&gt;
&lt;dependency&gt;
  &lt;groupId&gt;io.vertx&lt;/groupId&gt;
  &lt;artifactId&gt;vertx-web-client&lt;/artifactId&gt;
&lt;/dependency&gt;

&lt;!-- Mutiny API --&gt;
&lt;dependency&gt;
  &lt;groupId&gt;io.smallrye.reactive&lt;/groupId&gt;
  &lt;artifactId&gt;smallrye-mutiny-vertx-web-client&lt;/artifactId&gt;
&lt;/dependency&gt;

&lt;!-- Axle API --&gt;
&lt;dependency&gt;
  &lt;groupId&gt;io.smallrye.reactive&lt;/groupId&gt;
  &lt;artifactId&gt;smallrye-axle-web-client&lt;/artifactId&gt;
&lt;/dependency&gt;

&lt;!-- RX Java 2 API --&gt;
&lt;dependency&gt;
  &lt;groupId&gt;io.vertx&lt;/groupId&gt;
  &lt;artifactId&gt;vertx-rx-java2&lt;/artifactId&gt;
&lt;/dependency&gt;</code></pre>
</div>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
The <code>vertx-rx-java2</code> provides the RX Java 2 API for the whole Vert.x stack, not only the web client.
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>In this guide, we are going to use the Mutiny API, so:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="xml" class="language-xml hljs">&lt;dependency&gt;
  &lt;groupId&gt;io.smallrye.reactive&lt;/groupId&gt;
  &lt;artifactId&gt;smallrye-mutiny-vertx-web-client&lt;/artifactId&gt;
&lt;/dependency&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Now, create a new resource in your project with the following content:</p>
</div>
<div class="listingblock">
<div class="title">src/main/java/org/acme/vertx/ResourceUsingWebClient.java</div>
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">package org.acme.vertx;


import javax.annotation.PostConstruct;
import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

import io.smallrye.mutiny.Uni;
import org.jboss.resteasy.annotations.jaxrs.PathParam;

import io.vertx.mutiny.core.Vertx;
import io.vertx.mutiny.ext.web.client.WebClient;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.web.client.WebClientOptions;

@Path("/fruit-data")
public class ResourceUsingWebClient {

    @Inject
    Vertx vertx;

    private WebClient client;

    @PostConstruct
    void initialize() {
        this.client = WebClient.create(vertx,
                new WebClientOptions().setDefaultHost("fruityvice.com")
                    .setDefaultPort(443).setSsl(true).setTrustAll(true));
    }

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    @Path("/{name}")
    public Uni&lt;JsonObject&gt; getFruitData(@PathParam("name") String name) {
        return client.get("/api/fruit/" + name)
                .send()
                .onItem().transform(resp -&gt; {
                    if (resp.statusCode() == 200) {
                        return resp.bodyAsJsonObject();
                    } else {
                        return new JsonObject()
                                .put("code", resp.statusCode())
                                .put("message", resp.bodyAsString());
                    }
                });
    }

}</code></pre>
</div>
</div>
<div class="paragraph">
<p>This resource creates a <code>WebClient</code> and upon request use this client to invoke the <em>fruityvice</em> API.
Depending on the result the response is forwarded as it&#8217;s received, or a new JSON object is created with the status and body.
The <code>WebClient</code> is obviously asynchronous (and non-blocking), to the endpoint returns a <code>Uni</code>.</p>
</div>
<div class="paragraph">
<p>Run the application with:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="shell" class="language-shell hljs">./mvnw compile quarkus:dev</code></pre>
</div>
</div>
<div class="paragraph">
<p>And then, open a browser to: <code><a href="http://localhost:8080/fruit-data/pear" class="bare">http://localhost:8080/fruit-data/pear</a></code>. You should get some details about pears.</p>
</div>
<div class="paragraph">
<p>The application can also run as a native executable.
But, first, we need to instruct Quarkus to enable <em>ssl</em>.
Open the <code>src/main/resources/application.properties</code> and add:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-none hljs">quarkus.ssl.native=true</code></pre>
</div>
</div>
<div class="paragraph">
<p>Then, create the native executable with:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="shell" class="language-shell hljs">./mvnw package -Pnative</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="deploying-verticles"><a class="anchor" href="#deploying-verticles"></a>Deploying verticles</h2>
<div class="sectionbody">
<div class="paragraph">
<p><a href="https://vertx.io/docs/vertx-core/java/#_verticles">Verticles</a> is "a simple, scalable, actor-like deployment and concurrency model" provided by _Vert.x_.
This model does not claim to be a strict actor-model implementation, but it does share similarities especially with respect to concurrency, scaling and deployment.
To use this model, you write and <em>deploy</em> verticles, communicating with each other by sending messages on the event bus.</p>
</div>
<div class="paragraph">
<p>You can deploy <em>verticles</em> in Quarkus.
It supports:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><em>bare</em> verticle - Java classes extending <code>io.vertx.core.AbstractVerticle</code></p>
</li>
<li>
<p><em>Mutiny</em> verticle - Java classes extending <code>io.smallrye.mutiny.vertx.core.AbstractVerticle</code></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>To deploy verticles, use the regular Vert.x API:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">@Inject Vertx vertx;

// ...
vertx.deployVerticle(MyVerticle.class.getName(), ar -&gt; { });
vertx.deployVerticle(new MyVerticle(), ar -&gt; { });</code></pre>
</div>
</div>
<div class="paragraph">
<p>You can also pass deployment options to configure the verticle as well as set the number of instances.</p>
</div>
<div class="paragraph">
<p>Verticles are not <em>beans</em> by default.
However, you can implement them as <em>ApplicationScoped</em> beans and get injection support:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">package io.quarkus.vertx.verticles;

import io.smallrye.mutiny.Uni;
import io.smallrye.mutiny.vertx.core.AbstractVerticle;
import org.eclipse.microprofile.config.inject.ConfigProperty;

import javax.enterprise.context.ApplicationScoped;

@ApplicationScoped
public class MyBeanVerticle extends AbstractVerticle {

    @ConfigProperty(name = "address") String address;

    @Override
    public Uni&lt;Void&gt; asyncStart() {
        return vertx.eventBus().consumer(address)
                .handler(m -&gt; m.replyAndForget("hello"))
                .completionHandler();
    }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>You don&#8217;t have to inject the <code>vertx</code> instance but instead leverage the instance stored in the protected field of <code>AbstractVerticle</code>.</p>
</div>
<div class="paragraph">
<p>Then, deploy the verticle instance with:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">package io.quarkus.vertx.verticles;

import io.quarkus.runtime.StartupEvent;
import io.vertx.mutiny.core.Vertx;

import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.event.Observes;

@ApplicationScoped
public class VerticleDeployer {

    public void init(@Observes StartupEvent e, Vertx vertx, MyBeanVerticle verticle) {
         vertx.deployVerticle(verticle).await().indefinitely();
    }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>If you want to deploy every exposed <code>AbstractVerticle</code>, you can use:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">public void init(@Observes StartupEvent e, Vertx vertx, Instance&lt;AbstractVerticle&gt; verticles) {
    for (AbstractVerticle verticle : verticles) {
        vertx.deployVerticle(verticle).await().indefinitely();
    }
}</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="listening-to-a-unix-domain-socket"><a class="anchor" href="#listening-to-a-unix-domain-socket"></a>Listening to a Unix Domain Socket</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Listening on a unix domain socket allows us to dispense with the overhead of TCP
if the connection to the quarkus service is established from the same host. This can happen
if access to the service goes through a proxy which is often the case
if you&#8217;re setting up a service mesh with a proxy like Envoy.</p>
</div>
<div class="admonitionblock important">
<table>
<tr>
<td class="icon">
<i class="fa icon-important" title="Important"></i>
</td>
<td class="content">
This will only work on platforms that support <a href="#native-transport">Native Transport</a>.
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>To setup please enable the appropriate <a href="#native-transport">Native Transport</a> and set the following
environment property:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>quarkus.http.domain-socket=/var/run/io.quarkus.app.socket
quarkus.http.domain-socket-enabled=true</pre>
</div>
</div>
<div class="paragraph">
<p>By itself this will not disable the tcp socket which by default will open on
<code>0.0.0.0:8080</code>. It can be explicitly disabled:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>quarkus.http.host-enabled=false</pre>
</div>
</div>
<div class="paragraph">
<p>These properties can be set through Java&#8217;s <code>-D</code> command line parameter or
on <code>application.properties</code>.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="read-only-deployment-environments"><a class="anchor" href="#read-only-deployment-environments"></a>Read only deployment environments</h2>
<div class="sectionbody">
<div class="paragraph">
<p>In environments with read only file systems you may receive errors of the form:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-none hljs">java.lang.IllegalStateException: Failed to create cache dir</code></pre>
</div>
</div>
<div class="paragraph">
<p>Assuming <code>/tmp/</code> is writeable this can be fixed by setting the <code>vertx.cacheDirBase</code> property to point to a directory in <code>/tmp/</code> for instance in OpenShift by creating an environment variable <code>JAVA_OPTS</code> with the value <code>-Dvertx.cacheDirBase=/tmp/vertx</code>.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="running-behind-a-reverse-proxy"><a class="anchor" href="#running-behind-a-reverse-proxy"></a>Running behind a reverse proxy</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Quarkus could be accessed through proxies that additionally generate headers (e.g. <code>X-Forwarded-Host</code>) to keep
information from the client-facing side of the proxy servers that is altered or lost when they are involved.
In those scenarios, Quarkus can be configured to automatically update information like protocol, host, port and URI
reflecting the values in these headers.</p>
</div>
<div class="admonitionblock important">
<table>
<tr>
<td class="icon">
<i class="fa icon-important" title="Important"></i>
</td>
<td class="content">
Activating this feature makes the server exposed to several security issues (i.e. information spoofing).
Consider activate it only when running behind a reverse proxy.
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>To setup this feature, please include the following lines in <code>src/main/resources/application.properties</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-none hljs">quarkus.http.proxy-address-forwarding=true</code></pre>
</div>
</div>
<div class="paragraph">
<p>To consider only de-facto standard header (<code>Forwarded</code> header), please include the following lines in <code>src/main/resources/application.properties</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-none hljs">quarkus.http.allow-forwarded=true</code></pre>
</div>
</div>
<div class="paragraph">
<p>To consider only non-standard headers, please include the following lines instead in <code>src/main/resources/application.properties</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-none hljs">quarkus.http.proxy-address-forwarding=true
quarkus.http.proxy.enable-forwarded-host=true
quarkus.http.proxy.enable-forwarded-prefix=true</code></pre>
</div>
</div>
<div class="paragraph">
<p>Both configurations related with standard and non-standard headers can be combine.
In this case, the <code>Forwarded</code> header will have precedence in presence of both set of headers.</p>
</div>
<div class="paragraph">
<p>Supported forwarding address headers are:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>Forwarded</code></p>
</li>
<li>
<p><code>X-Forwarded-Proto</code></p>
</li>
<li>
<p><code>X-Forwarded-Host</code></p>
</li>
<li>
<p><code>X-Forwarded-Port</code></p>
</li>
<li>
<p><code>X-Forwarded-Ssl</code></p>
</li>
<li>
<p><code>X-Forwarded-Prefix</code></p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect1">
<h2 id="going-further"><a class="anchor" href="#going-further"></a>Going further</h2>
<div class="sectionbody">
<div class="paragraph">
<p>There are many other facets of Quarkus using Vert.x underneath:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>The event bus is the connecting tissue of Vert.x applications.
Quarkus integrates it so different beans can interact with asynchronous messages.
This part is covered in the <a href="reactive-event-bus">event bus documentation</a>.</p>
</li>
<li>
<p>Data streaming and Apache Kafka are a important parts of modern systems.
Quarkus integrates data streaming using Reactive Messaging.
More details on <a href="kafka">Interacting with Kafka</a>.</p>
</li>
<li>
<p>Learn how to implement highly performant, low-overhead database applications on Quarkus with the <a href="reactive-sql-clients">Reactive SQL Clients</a>.</p>
</li>
</ul>
</div>
</div>
</div>
    </div>
  </div>
</div>

  </div>

  <div class="content project-footer">
  <div class="footer-section">
    <div class="logo-wrapper">
      <a href="/"><img src="/assets/images/quarkus_logo_horizontal_rgb_reverse.svg" class="project-logo" title="Quarkus"></a>
    </div>
  </div>
  <div class="grid-wrapper">
    <p class="grid__item width-3-12">Quarkus is open. All dependencies of this project are available under the <a href='https://www.apache.org/licenses/LICENSE-2.0' target='_blank'>Apache Software License 2.0</a> or compatible license.<br /><br />This website was built with <a href='https://jekyllrb.com/' target='_blank'>Jekyll</a>, is hosted on <a href='https://pages.github.com/' target='_blank'>Github Pages</a> and is completely open source. If you want to make it better, <a href='https://github.com/quarkusio/quarkusio.github.io' target='_blank'>fork the website</a> and show us what you’ve got.</p>

    
      <div class="width-1-12 project-links">
        <span>Navigation</span>
        <ul class="footer-links width-1-12">
          
            <li><a href="/">Home</a></li>
          
            <li><a href="/guides">Guides</a></li>
          
            <li><a href="/community/#contributing">Contribute</a></li>
          
            <li><a href="/faq">FAQ</a></li>
          
            <li><a href="/get-started">Get Started</a></li>
          
        </ul>
      </div>
    
      <div class="width-1-12 project-links">
        <span>Contribute</span>
        <ul class="footer-links width-1-12">
          
            <li><a href="https://twitter.com/quarkusio">Follow us</a></li>
          
            <li><a href="https://github.com/quarkusio">GitHub</a></li>
          
            <li><a href="/security">Security&nbsp;policy</a></li>
          
        </ul>
      </div>
    
      <div class="width-1-12 project-links">
        <span>Get Help</span>
        <ul class="footer-links width-1-12">
          
            <li><a href="https://groups.google.com/forum/#!forum/quarkus-dev">Forums</a></li>
          
            <li><a href="https://quarkusio.zulipchat.com">Chatroom</a></li>
          
        </ul>
      </div>
    

    
      <div class="width-3-12 more-links">
        <span>Quarkus is made of community projects</span>
        <ul class="footer-links">
          
            <li><a href="https://vertx.io/" target="_blank">Eclipse Vert.x</a></li>
          
            <li><a href="https://microprofile.io" target="_blank">Eclipse MicroProfile</a></li>
          
            <li><a href="https://hibernate.org" target="_blank">Hibernate</a></li>
          
            <li><a href="https://netty.io" target="_blank">Netty</a></li>
          
            <li><a href="https://resteasy.github.io" target="_blank">RESTEasy</a></li>
          
            <li><a href="https://camel.apache.org" target="_blank">Apache Camel</a></li>
          
            <li><a href="https://code.quarkus.io/" target="_blank">And many more...</a></li>
          
        </ul>
      </div>
    
  </div>
</div>
  <div class="content redhat-footer">
  <div class="grid-wrapper">
    <span class="licence">
      <i class="fab fa-creative-commons"></i><i class="fab fa-creative-commons-by"></i> <a href="https://creativecommons.org/licenses/by/3.0/" target="_blank">CC by 3.0</a> | <a href="https://www.redhat.com/en/about/privacy-policy">Privacy Policy</a>
    </span>
    <span class="redhat">
      Sponsored by
    </span>
    <span class="redhat-logo">
      <a href="https://www.redhat.com/" target="_blank"><img src="/assets/images/redhat_reversed.svg"></a>
    </span>
  </div>
</div>


  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js" integrity="sha384-8gBf6Y4YYq7Jx97PIqmTwLPin4hxIzQw5aDmUg/DDhul9fFpbbLcLh3nTIIDJKhx" crossorigin="anonymous"></script>
  <script type="text/javascript" src="/assets/javascript/mobile-nav.js"></script>
  <script type="text/javascript" src="/assets/javascript/scroll-down.js"></script>
  <script src="/assets/javascript/satellite.js" type="text/javascript"></script>
  <script src="https://quarkus.io/guides/javascript/config.js" type="text/javascript"></script>
  <script src="/assets/javascript/search-filter.js" type="text/javascript"></script>
  <script src="/assets/javascript/back-to-top.js" type="text/javascript"></script>
</body>

</html>
